﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Yeap.Kernel.Security;
using Yeap.Kernel.Storage;
using Yeap.Kernel.Utils;
using Yeap.Kernel.Utils.Enums;
using Yeap.Kernel.Utils.Extensions;
using Yeap.Models;

namespace Yeap.Controllers
{
    public class WorkController : Controller
    {
        private static WorkRepository WorkRepository
        {
            get { return new WorkRepository(); }
        }

        public override string Name
        {
            get
            {
                return "Work";
            }
        }

        private static ProfessorRepository ProfessorRepository
        {
            get
            {
                return new ProfessorRepository();
            }
        }

        private static StudentRepository StudentRepository
        {
            get
            {
                return new StudentRepository();
            }
        }

        //
        // GET: /Work/
        public ActionResult Index()
        {
            var course = TryGetIntParam("course", 0);
            var year = TryGetIntParam("year", 0);
            var workType = (WorkTypes) TryGetIntParam("workType", 0);
            var professorId = TryGetIntParam("professor", 0);
            Professor professor = ProfessorRepository.GetById(professorId);
            var workList = WorkRepository.GetWorks(course, workType, professor, year);

            WorkListModel model = new WorkListModel();
            model.SelectedCourse = course;
            model.SelectedProfessor = professor;
            model.SelectedWorkType = workType;
            model.SelectedYear = year;
            model.Works = new List<WorkListItem>();

            foreach (var work in workList)
            {
                model.Works.Add(new WorkListItem
                                    {
                                        WorkId = work.Id,
                                        Work = work,
                                        WorkTitle = work.WorkTitle,
                                        Year = work.Year,
                                        Teacher = ProfessorRepository.GetById(work.ProfessorId),
                                        Student = work.UserWorks.Where(uw => uw.Type == AssignmentTypes.Agreement || uw.Type == AssignmentTypes.Finished).Select(uw => (new StudentRepository()).GetById(uw.UserId)).FirstOrDefault(),
                                        AssignedStudents = work.UserWorks.Where(uw => uw.Type == AssignmentTypes.StudentProposal).Select(uw => (new StudentRepository()).GetById(uw.UserId)).ToList(),
                                        ProposedStudents = work.UserWorks.Where(uw => uw.Type == AssignmentTypes.ProfessorProposal).Select(uw => (new StudentRepository()).GetById(uw.UserId)).ToList(),
                                        WorkType = work.GetWorkType(),
                                    }
                    );
            }

            model = BindCourses(model);
            model = BindYears(model);
            model = BindProfessors(model);
            model = BindWorkTypes(model);
            
            return View(model);
        }

        private WorkListModel BindCourses(WorkListModel model)
        {
            List<NameValueItem> availableCourses = new List<NameValueItem>();
            var minCourse = SiteSettingPool.MinimalCourse;
            var maxCourse = SiteSettingPool.MinimalCourse;
        
            availableCourses.Add(new NameValueItem {Name = "Все курсы", Value = 0.ToString()});
            for (int i = minCourse; i<=maxCourse; i++)
            {
                availableCourses.Add(new NameValueItem {Name = String.Format("{0} курс", i), Value = i.ToString()});
            }
            model.AvailableCourses = availableCourses;
            return model;
        }

        private WorkListModel BindYears(WorkListModel model)
        {
            List<NameValueItem> availableYears = new List<NameValueItem>();
            var minYear = SiteSettingPool.InitialYear;
            var currYear = SiteSettingPool.CurrentYear;

            availableYears.Add(new NameValueItem {Name = "Все года", Value = 0.ToString()});
            for (int i = minYear; i <= currYear; i++)
            {
                availableYears.Add(new NameValueItem {Name = String.Format("{0} - {1}", i, i + 1), Value = i.ToString()});
            }
            model.AvailableYears = availableYears;
            return model;
        }

        private WorkListModel BindProfessors (WorkListModel model)
        {
            List<NameValueItem> availableProfessors = new List<NameValueItem>();

            availableProfessors.Add(new NameValueItem {Name = "Все профессоры", Value = 0.ToString()});
            var allProfessors = ProfessorRepository.GetAll();
            foreach (var professor in allProfessors)
            {
                availableProfessors.Add(new NameValueItem {Name = professor.FullName, Value = professor.Id.ToString()});
            }
            model.AvailableProfessors = availableProfessors;
            return model;
        }

        private WorkListModel BindWorkTypes(WorkListModel model)
        {
            List<NameValueItem> availableWorkTypes = new List<NameValueItem>();

            availableWorkTypes.Add(new NameValueItem {Name = "Любой", Value = 0.ToString()});
            availableWorkTypes.Add(new NameValueItem {Name="Работы прошлых лет", Value = "1"});
            availableWorkTypes.Add(new NameValueItem {Name="Открытые",Value = "2"});
            availableWorkTypes.Add(new NameValueItem {Name = "Выполняемые", Value = "3"});
            availableWorkTypes.Add(new NameValueItem {Name = "Завершённые", Value = "4"});

            model.AvailableWorkTypes = availableWorkTypes;
            return model;
        }

        
        public ActionResult GetStudentList(WorkListModel workListModel, Int32 workId)
        {
            var workListItem = workListModel.Works[workId - 1];
            return View(workListItem);
        }

        public ActionResult Show(Int32 id)
        {
            var targetWork = WorkRepository.GetById(id);
            var model = new SingleWorkModel();
            model.Work = targetWork;
            model.WorkType = targetWork.GetWorkType();
            model.Comments = targetWork.WorkComment.ToList();
            model.Files = targetWork.WorkFile.ToList();
            model.History = targetWork.GetHistory();
            model.Professor = ProfessorRepository.GetById(targetWork.ProfessorId);
            model.UserWorks = targetWork.UserWorks.ToList();
            return View(model);
        }

        public ActionResult LoadInfo(Int32 workId, String activeTab)
        {
            var targetWork = WorkRepository.GetById(workId);
            switch (activeTab)
            {
                case "History":
                    var historyModel = targetWork.GetHistory();
                    return PartialView("HistoryBlock", historyModel);
                case "Files":
                    var filesModel = new FileBlockModel();
                    filesModel.Files = targetWork.WorkFile.ToList();
                    filesModel.Work = targetWork;
                    return PartialView("FilesBlock", filesModel);
                case "AdditionalInfo":
                    return PartialView("AdditionalInfoBlock", targetWork);
                case "Students":
                    var studentsModel = new StudentBlockModel();
                    studentsModel.Students = targetWork.UserWorks.ToList();
                    studentsModel.Work = targetWork;
                    return PartialView("StudentsBlock", studentsModel);
                case "Comments":
                    var commentModel = new CommentBlockModel();
                    commentModel.Comments = targetWork.WorkComment.ToList();
                    commentModel.Work = targetWork;
                    return PartialView("CommentBlock", commentModel);
                default:
                    throw new NotSupportedException("Unknown tab clicked");
            }
//            var model = targetWork.GetHistory();
  //          return View("Index");
        }

        public ActionResult AddComment(Int32 workId, String commentText)
        {
             (new WorkCommentRepository()).Add(new WorkComment {Date = DateTime.Now, Text = commentText, UserId = LoginUtils.CurrentUser.Id, WorkId = workId});
            return RedirectToAction("Show", new RouteValueDictionary {{"id", workId}});
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Upload(FormCollection formValues)
        {
            var workId = TryGetIntParam("workUploadId", 0);

            foreach (string inputTagName in Request.Files)
            {
                string description = Request.Form["Description"];
                HttpPostedFileBase file = Request.Files[inputTagName];

                if (file != null && file.ContentLength > 0)
                {
                    string uniqueFileName = String.Concat(DateTime.Now.TimeStamped(), file.FileName);
                    string filePath = Path.Combine(HttpContext.Server.MapPath("~/Content/Upload"),
                                                   Path.GetFileName(uniqueFileName));
                    file.SaveAs(filePath);
                    (new UploadedFileRepository()).Add(new UploadedFile
                                                           {
                                                               FileDescription = description,
                                                               FileName = uniqueFileName,
                                                               FileSize = file.ContentLength,
                                                               Time = DateTime.Now,
                                                               UserId = LoginUtils.CurrentUser.Id,
                                                           }
                        );
                    var uploadedFileId =
                        (new UploadedFileRepository()).GetAll().Where(uf => uf.FileName.EqualsIgnoreCase(uniqueFileName))
                            .FirstOrDefault().Id;
                    (new WorkFileRepository()).Add(new WorkFile
                                                       {
                                                           WorkId = workId,
                                                           FileId = uploadedFileId,
                                                       }
                        );
                }
                else
                    return Content("Upload Error");

            }
            return RedirectToAction("Show", new RouteValueDictionary {{"id", workId}});
            //return View("Index");
        }

        public ActionResult Edit (int id)
        {
            return View(WorkRepository.GetById(id));
        }

        [HttpPost]
        public ActionResult Edit (Work editedWork)
        {
            if (ModelState.IsValid)
            {
                var workRepository = WorkRepository;
                var work = workRepository.GetById(editedWork.Id);
                work.WorkTitle = editedWork.WorkTitle;
                workRepository.Update();
                return RedirectToAction("Show", new {id = editedWork.Id});
            }
            else
            {
                return View(editedWork);
            }
        }
    }
}
